
/*
 * 构造函数模式
 * 优点：
 * 缺点：每个sayName() 方法都要在示例上重新创建一遍，这里已经解决
 */
function Person(name, age, job) {
	this.name = name;
	this.age = age;
	this.job = job;
	this.sayName = sayName;
}

function sayName() {
	console.log("hello!,My name is " + this.name);
}

/*原型模式 //每个函数都有prototype（原型）属性
 * isPrototypeOf() 方法来确定对象之间是否存在这种关系
 * Object.getPrototypeOf() 返回[[Prototype]]的值
 * hasOwnProperty() 判断给定属性是否存在于对象实例中，返回true
 * in 访问给定属性，返回true
 * Object.keys() 取得对象上所有可枚举的实例属性
 * Object.getOwnPeopertyName() 取得所有实例属性，无论是否可枚举
 * constructor 属性指向Person，可重写
 * 
 */
function Person() {}

Person.prototype.name = "Trowing";
Person.prototype.age = 25;
Person.prototype.sayName = function() {
	console.log("hello,My name is " + this.name);
}

function hasPrototypeProperty(object, name) {
	return !object.hasOwnProperty(name) && (name in object);
}

//组合使用构造函数模式和原型模式
function Person(name, age, job) {
	this.name = name;
	this.age = age;
	this.job = job;
	this.friend = ["Shelby", "Court"];
}

Person.prototype = {
	constructor: Person,
	sayName: function() {
		console.log(this.name);
	}
}

//动态原型模式
function Person(name, age, job) {
	//属性
	this.name = name;
	this.age = age;
	this.job = job;

	//方法
	if (typeof this.sayName != "function") {
		Person.prototype.sayName = function() {
			console.log("你好，我是" + this.name);
		}
	}
}

//稳妥构造函数模式  //适合在某些安全执行环境
function Person(name, age, job) {
	//创建要返回的对象
	var o = new Object();

	//可以在这里定义私有变量和函数

	//添加方法
	o.sayName = function() {
		alert(name);
	}

	//返回对象
	return o;
}

//借用构造函数，缺点：函数不可复用
function SuperType(name) {
	this.name = name;
}

function SubType() {
	//继承了SuperType，同时还传递了参数
	SuperType.call(this, "Nicholas");
	this.age = 29;
}
var instance = new SubType();
alert(instance.name);
alert(instance.age);

//组合继承
function SuperType(name) {
	this.name = name;
	this.colors["red", "blue", "green"];
}

SuperType.Prototype.sayName = function() {
	alert(this.name);
}

function SubType(name, age) {
	//继承属性
	SuperType.call(this, name);
	this.age = age;
}

//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
	alert(this.age);
}

//原型式继承
// function object(o){
//     function F(){}
//     F.prototype=o;
//     return new F();
// }

var person = {
	name: "NOcholas",
	friends: ["Shelby", "Court", "Van"]
}

// var anotherPerson=object(person);
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

alert(person.friends);

var anotherPer = Object.create(person, {
	name: {
		value: "Trowring"
	}
})
alert(anotherPer.name);

//寄生组合式继承
function inheritPrototype(subType, superType) {
	var prototype = Object(superType.prototype); //创建对象
	prototype.constructor = subType; //增强对象
	subType.prototype = prototype; //指定对象
}

/*
 * 七、函数表达式
 * 递归
 * 闭包
 */

//递归
function factorial(num) {
	if (num <= 1) {
		return 1;
	} else {
		// return num*arguments.callee(num-1);  //arguments.callee();指向正在执行函数的指针
		return num * f(num - 1); //严格模式下使用命名函数表达式
	}
}

//闭包
function conpeare(valuel, valuel2) {
	if (valuel < valuel2) {
		return -1;
	} else if (valuel > valuel2) {
		return 1;
	} else {
		return 0;
	}
}

/*
 * 块级作用域
 */
(function() {
	//这里是块级作用域
})();

var someFunction = function() {
	//这里是块级作用域
}
sommeFunction();

function outputNumbers(count) {
	(function() {
		//这里是私有作用域
	})();
}

/*
 * 私有变量
 */
//特权方法
function MyObject() {
	//私有变量和私有函数
	var privateVariable = 10;

	function privateFuntion() {
		return false;
	}

	//特权方法
	this.publicMethod = function() {
		privateVariable++;
		return privateFunction();
	}
}

//静态私有变量
(function() {
	//私有变量和私有函数
	var privateVariable = 10;

	function privateFunction() {
		return false;
	}

	//构造函数
	MyObject = function() {};

	//公有/特权方法
	MyObject.prototype.publicMethod = function() {
		privateVariable++;
		privateFunction();
	};
})();

//模式模块
var singleton = function() {
	//私有变量和私有函数
	var privateVariable = 10;

	function privateFunction() {
		return false;
	}

	//特权/公有方法和属性
	return {
		publicProperty: true;
		publicMethod: function() {
			privateVariable++;
			return privateFunction();
		}
	}
}

//增强的模块模式
var singleton = function() {
	//私有变量和私有方法
	var privateVariable = 10;

	function privateFunction() {
		return false;
	}

	//创建对象
	var object = new CustomType();

	//添加特权/公有属性和方法
	object.pulicProperty = true;

	object.publicMethoc = function() {
		privateVariable++;
		return privateFunction();
	}

	//返回这个对象
	return object;
}();

var application = function() {
	//私有变量和属性
	var components = new Array();

	//初始化
	components.push(new BaseComponent());

	//创建application的一个局部副本
	var app = new BaseComponent();

	//公共接口
	app.getComponentCount = function() {
		return components.length;
	};

	app.registerComponent = function(component) {
		if (typeOf compenont == "object") {
			conpenont.push(compenont);
		}
	};

	//返回这个副本
	return app;
}();

//对象写法
var module=new Object({
    _count:0,
    number1:function(){

    },
    number2:function(){
      //
    }
});

//立即执行函数写法
//可以达到不暴露隐私成员
var module2=(function(){
    var _count = 0;
    var number1 = function(){
    	//
    };
    var number2 = function(){
    	//
    };
    return{
        m1:number1,
        m2:number2
    };
})();

//放大模式
//如果一个模块很大，必须分成几个部分，或者一个模块需要继承另一个模块，这时就有必要采用"放大模式"
var module3=(function(mod){
    mod.m3=function(){
        //
    };
    return mod;
})(module3);

//宽放大模式
//在浏览器环境中，模块的各个部分通常都是从网上获取的，有时无法知道哪个部分会先加载。
//如果采用上一节的写法，第一个执行的部分有可能加载一个不存在空对象，这时就要采用"宽放大模式"
var module4=(function(mod){
    //
    return mod;

})(window.module4 || {})

//输入全局变量
//独立性是模块的重要特点，模块内部最好不与程序的其他部分直接交互。
//为了在模块内部调用全局变量，必须显式地将其他变量输入模块。
var module=(function($,YAHOO){
    //
})(jQuery,YAHOO);

//AMD 异步模块定义
